package com.laizhenghua.wxstub.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.laizhenghua.wxstub.constant.AppConstant;
import com.laizhenghua.wxstub.dto.WxUserDTO;
import com.laizhenghua.wxstub.entiry.TemplateParam;
import com.laizhenghua.wxstub.service.AssistantService;
import com.laizhenghua.wxstub.service.CacheService;
import com.laizhenghua.wxstub.service.MessageService;
import com.laizhenghua.wxstub.utils.CalendarUtil;
import com.mongodb.client.result.DeleteResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.client.RestTemplate;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * @description:
 * @author: laizhenghua
 * @date: 2022/8/30 12:42
 */
@Service("assistantService")
public class AssistantServiceImpl implements AssistantService {
    private static final org.apache.logging.log4j.Logger log = org.apache.logging.log4j.LogManager.getLogger(AssistantServiceImpl.class);
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private CacheService cacheService;
    @Autowired
    private MessageService messageService;
    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public JSONObject pushMessage() {
        // 1.获取access_token
        String accessToken = cacheService.getAccessToken();
        if (accessToken == null) {
            log.info("获取access_token失败!");
            return null;
        }
        // 2.获取发送微信用户
        List<WxUserDTO> wxUserList = mongoTemplate.findAll(WxUserDTO.class);
        if (CollectionUtils.isEmpty(wxUserList)) {
            log.info("发送微信用户为空！");
            return null;
        }
        JSONObject result = new JSONObject();
        for (WxUserDTO wxUser : wxUserList) {
            // 3.构造请求体
            JSONObject body = getRequestBody(wxUser.getCity(), wxUser.getWxId(), wxUser.getDate(), wxUser.getTemplateId(), wxUser.getCount());
            log.info("request body -> " + JSON.toJSONString(body));
            HttpHeaders headers = new HttpHeaders();
            MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
            // 4.发送消息
            headers.setContentType(type);
            headers.add("Accept", MediaType.APPLICATION_JSON.toString());
            HttpEntity<String> formEntity = new HttpEntity<>(body.toString(), headers);
            JSONObject response = restTemplate.postForObject(AppConstant.WX_BASE_URL + "message/template/send?access_token=" + accessToken, formEntity,
                    JSONObject.class);
            if (response == null) {
                continue;
            }
            log.info(JSON.toJSONString(response));
            result.put(wxUser.getName(), response.getString("errmsg"));
            wxUser.setCount(wxUser.getCount() + 1);
            mongoTemplate.save(wxUser);
        }
        return result;
    }
    private JSONObject getRequestBody(String city, String wxId, String date, String templateId, Integer count) {
        JSONObject requestData = new JSONObject();
        // 打招呼
        requestData.put("g", TemplateParam.builder().setColor("#E38EFF").setValue(getGreetings()));
        // 当前城市
        requestData.put("c", TemplateParam.builder().setColor("#33FF33").setValue(city));
        // 构造天气信息
        JSONObject weatherInfo = messageService.getWeatherInfo(city);
        // 日期
        String e1 = String.valueOf(Character.toChars(0x1F4C5));
        requestData.put("e1", TemplateParam.builder().setValue(e1));
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
        sdf.format(new Date());
        requestData.put("d", TemplateParam.builder().setColor("#B088FF").setValue(sdf.format(new Date())));
        // 星期
        requestData.put("w", TemplateParam.builder().setColor("#9F88FF").setValue(weatherInfo.getString("week")));

        // 今天天气情况
        String e2 = String.valueOf(Character.toChars(0x26C5));
        requestData.put("e2", TemplateParam.builder().setValue(e2));
        requestData.put("we", TemplateParam.builder().setColor("#9999FF").setValue(weatherInfo.getString("wea")));
        // requestData.put("weatherNote", TemplateParam.builder().setColor("#ff6680").setValue(getWeatherNote(weatherInfo)));

        // 当前温度
        String e3 = String.valueOf(Character.toChars(0x1F34F));
        requestData.put("e3", TemplateParam.builder().setValue(e3));
        requestData.put("td", TemplateParam.builder().setColor("#99BBFF").setValue(weatherInfo.getString("tem_day") + "℃"));
        requestData.put("tn", TemplateParam.builder().setColor("#99BBFF").setValue(weatherInfo.getString("tem_night") + "℃"));

        // 空气湿度
        String e4 = String.valueOf(Character.toChars(0x1F4A6));
        requestData.put("e4", TemplateParam.builder().setValue(e4));
        requestData.put("h", TemplateParam.builder().setColor("#CC00FF").setValue(weatherInfo.getString("humidity")));

        // 空气质量
        String e5 = String.valueOf(Character.toChars(0x1F637));
        requestData.put("e5", TemplateParam.builder().setValue(e5));
        requestData.put("a", TemplateParam.builder().setColor("#66FF66").setValue(getAirLevel(weatherInfo.getInteger("air"))));

        // 风向与风力
        String e6 = String.valueOf(Character.toChars(0x1F300));
        requestData.put("e6", TemplateParam.builder().setValue(e6));
        requestData.put("ws", TemplateParam.builder().setColor("#FF8800").setValue(getWinSpeed(weatherInfo)));

        // 微博热搜
        String e7 = String.valueOf(Character.toChars(0x1F340));
        requestData.put("e7", TemplateParam.builder().setValue(e7));
        JSONArray wbHostArray = messageService.getWbHost(3);
        // #E38EFF
        requestData.put("b1", TemplateParam.builder().setValue(wbHostArray.getJSONObject(0).getString("keyword")));
        requestData.put("b2", TemplateParam.builder().setValue(wbHostArray.getJSONObject(1).getString("keyword")));
        requestData.put("b3", TemplateParam.builder().setValue(wbHostArray.getJSONObject(2).getString("keyword")));

        // CSDN热搜
        String e8 = String.valueOf(Character.toChars(0x1F342));
        requestData.put("e8", TemplateParam.builder().setValue(e8));
        JSONArray csdnHostArray = messageService.getCsdnHost(3);
        requestData.put("c1", TemplateParam.builder().setColor("").setValue(csdnHostArray.getJSONObject(0).getString("keyword")));
        // requestData.put("c2", TemplateParam.builder().setColor("").setValue(csdnHostArray.getJSONObject(1).getString("keyword")));
        // requestData.put("c3", TemplateParam.builder().setColor("").setValue(csdnHostArray.getJSONObject(2).getString("keyword")));

        // 疫情提醒
        // requestData.put("yq", TemplateParam.builder().setColor("#e06f1f").setValue(""));

        // 网易云音乐评
        String e9 = String.valueOf(Character.toChars(0x1F343));
        requestData.put("e9", TemplateParam.builder().setValue(e9));
        String wyyContent = messageService.getWyyContent();
        requestData.put("y", TemplateParam.builder().setColor("").setValue(wyyContent));

        // 纪念日
        String e10 = String.valueOf(Character.toChars(0x231B));
        requestData.put("e10", TemplateParam.builder().setValue(e10));
        requestData.put("rt", TemplateParam.builder().setColor("#00DD77").setValue(date.split("/")[0]));
        Long remainDay = CalendarUtil.getRemainDay(date.split("/")[1]);
        requestData.put("rd", TemplateParam.builder().setColor("#00DD77").setValue(remainDay + ""));

        // 土味情话
        String content = messageService.getLoveContent();
        String e11 = String.valueOf(Character.toChars(0x1F33F));
        requestData.put("e11", TemplateParam.builder().setValue(e11));
        requestData.put("lt", TemplateParam.builder().setColor("#D28EFF").setValue(content));

        // 计时
        String e12 = String.valueOf(Character.toChars(0x1F4AA));
        requestData.put("e12", TemplateParam.builder().setValue(e12));
        requestData.put("ct", TemplateParam.builder().setColor("#33FFDD").setValue(count + ""));

        JSONObject body = new JSONObject();
        body.put("touser", wxId);
        body.put("template_id", templateId);
        body.put("data", requestData);
        return body;
    }
    private String getWinSpeed(JSONObject info) {
        return String.format(info.getString("win_speed") + "(%s)", info.getString("win"));
    }
    private String getAirLevel(Integer air) {
        String level = null;
        if (air <= 50) {
            level = "优";
        } else if (air <= 100) {
            level = "良";
        } else {
            level = "轻度污染";
        }
        return level;
    }
    // 问候语
    private String getGreetings() {
        String greetings = null;
        Calendar calendar = Calendar.getInstance();
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        if (hour >= 6 && hour < 8) {
            greetings = "早呀，早呀！";
        } else if (hour >= 8 && hour < 11) {
            greetings = "早好呀！";
        } else if (hour >= 11 && hour < 13) {
            greetings = "中午好呀！";
        } else if (hour >= 13 && hour < 17) {
            greetings = "下午好呀！";
        } else if (hour >= 17 && hour < 19) {
            greetings = "下班了，下班了！";
        } else if (hour >= 19 && hour < 23) {
            greetings = "晚上好呀！";
        } else {
            greetings = "已经很晚了哦，记得早睡呀~";
        }
        return greetings;
    }

    public String getTime() {
        Calendar calendar= Calendar.getInstance();
        SimpleDateFormat dateFormat= new SimpleDateFormat("hh:mm");
        return dateFormat.format(calendar.getTime());
    }

    public String getWeatherNote(JSONObject weatherInfo) {
        String weatherNote = "";
        String wea = weatherInfo.getString("wea");
        String tem = weatherInfo.getString("tem");
        if (wea.contains("雨")) {
            weatherNote = "今天可能下雨哦，记得带伞~";
        }
        if (wea.contains("云")) {
            weatherNote = "今天天气还不错嘛~";
        }
        if (wea.contains("晴")) {
            weatherNote = "今天可能有点热哦~";
        }
        if (wea.contains("阴")) {
            weatherNote = "今天天气很凉爽~";
        }
        if (Integer.parseInt(tem) > 38) {
            weatherNote = "哇塞，今天好热，千万注意别中暑了哦~";
        }
        if (Integer.parseInt(tem) < 20) {
            weatherNote = "真冷啊，注意保暖~";
        }
        return String.format(wea + "（%s）", weatherNote);
    }
    @Override
    public List<WxUserDTO> getWxUserList(Integer pageSize, Integer pageNo) {
        if (pageSize == null || pageNo == null) {
            return mongoTemplate.findAll(WxUserDTO.class);
        }
        Pageable pageable = PageRequest.of(pageNo - 1, pageSize, Sort.by(Sort.Order.asc("_id")));
        Query query = new Query().with(pageable);
        return mongoTemplate.find(query, WxUserDTO.class);
    }

    @Override
    public WxUserDTO addWxUser(String wxId, String name, String city, String date, String templateId, Integer count, String password) {
        WxUserDTO wxUser = new WxUserDTO();
        wxUser.setWxId(wxId);
        wxUser.setName(name);
        wxUser.setCity(city);
        wxUser.setDate(date);
        wxUser.setTemplateId(templateId);
        wxUser.setCount(count);
        wxUser.setPassword(passwordEncoder.encode(password));
        return mongoTemplate.save(wxUser);
    }

    @Override
    public DeleteResult deleteWxUser(String _id) {
        Query query = Query.query(Criteria.where("_id").is(_id));
        DeleteResult result = mongoTemplate.remove(query, WxUserDTO.class);
        return result;
    }
}
